<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui"
    />
    <title>Android快速加载Dex | zzqhost</title>
    <meta name="description" content="天行健，君子以自强不息；地势坤，君子以厚德载物" />
    <meta property="og:type" content="website" />
    <meta property="og:title" content="Android快速加载Dex | zzqhost" />
    <meta property="og:site_name" content="Android快速加载Dex | zzqhost" />
    <meta property="og:locale" content="zh-CN" />
    <meta name="twitter:card" content="summary" />
    <meta name="twitter:title" content="Android快速加载Dex | zzqhost" />
    <link rel="shortcut icon" href="/favicon.ico">
    
    <link rel="preload" href="/assets/css/0.styles.948dbb0a.css" as="style"><link rel="preload" href="/assets/js/app.3e01f5cb.js" as="script"><link rel="preload" href="/assets/js/1.21aaee9f.js" as="script"><link rel="preload" href="/assets/js/14.98a4de9c.js" as="script"><link rel="preload" href="/assets/js/5.352c1a43.js" as="script"><link rel="preload" href="/assets/js/7.4a8a313c.js" as="script"><link rel="preload" href="/assets/js/9.5ce2172b.js" as="script"><link rel="preload" href="/assets/js/6.8b8fad13.js" as="script"><link rel="preload" href="/assets/js/22.7d278bc3.js" as="script"><link rel="preload" href="/assets/js/13.186562af.js" as="script"><link rel="preload" href="/assets/js/15.740f4afc.js" as="script"><link rel="prefetch" href="/assets/js/10.e3f309c4.js"><link rel="prefetch" href="/assets/js/11.7bef5ef0.js"><link rel="prefetch" href="/assets/js/12.cf546b2f.js"><link rel="prefetch" href="/assets/js/16.c0f3e779.js"><link rel="prefetch" href="/assets/js/17.ee3f21b3.js"><link rel="prefetch" href="/assets/js/18.2c35035c.js"><link rel="prefetch" href="/assets/js/19.e4881cfc.js"><link rel="prefetch" href="/assets/js/20.95040517.js"><link rel="prefetch" href="/assets/js/21.cdbb212e.js"><link rel="prefetch" href="/assets/js/23.1e2b813e.js"><link rel="prefetch" href="/assets/js/24.6cc55189.js"><link rel="prefetch" href="/assets/js/25.ea35ed40.js"><link rel="prefetch" href="/assets/js/26.2b97bfde.js"><link rel="prefetch" href="/assets/js/27.d323aa74.js"><link rel="prefetch" href="/assets/js/28.30416d07.js"><link rel="prefetch" href="/assets/js/29.02b97357.js"><link rel="prefetch" href="/assets/js/30.95aedede.js"><link rel="prefetch" href="/assets/js/31.79b824fd.js"><link rel="prefetch" href="/assets/js/32.d0cd6341.js"><link rel="prefetch" href="/assets/js/33.14c3c5b9.js"><link rel="prefetch" href="/assets/js/34.ac56f38e.js"><link rel="prefetch" href="/assets/js/35.54820345.js"><link rel="prefetch" href="/assets/js/36.37013d97.js"><link rel="prefetch" href="/assets/js/37.38353206.js"><link rel="prefetch" href="/assets/js/38.36296a20.js"><link rel="prefetch" href="/assets/js/39.37df68d6.js"><link rel="prefetch" href="/assets/js/4.54d65165.js"><link rel="prefetch" href="/assets/js/40.ffbd7a88.js"><link rel="prefetch" href="/assets/js/41.5db561d2.js"><link rel="prefetch" href="/assets/js/42.d876627b.js"><link rel="prefetch" href="/assets/js/43.e5008459.js"><link rel="prefetch" href="/assets/js/44.a24dc4a2.js"><link rel="prefetch" href="/assets/js/45.f696c4e1.js"><link rel="prefetch" href="/assets/js/8.8c0e5954.js"><link rel="prefetch" href="/assets/js/vendors~search.c4563fd1.js">
    <link rel="stylesheet" href="/assets/css/0.styles.948dbb0a.css">
  </head>
  <body>
    <div id="loader-wrapper" style="display: none;opacity:0">
      <div id="loader"></div>
      <div class="loader-section section-left"></div>
      <div class="loader-section section-right"></div>
    </div>
    <div id="app" data-server-rendered="true"><div style="height:100%;" data-v-80d5f2bc><section class="el-container main-container" data-v-80d5f2bc><aside class="el-aside menu" style="width:auto;" data-v-67e96130 data-v-80d5f2bc><ul role="menubar" class="menu-wrap el-menu" style="background-color:;" data-v-67e96130><li data-v-67e96130><div class="brand-wrap" style="background-image:url(/brand.jpg);" data-v-67e96130><div class="brand" data-v-67e96130><a href="/" class="avatar waves-effect waves-circle waves-light router-link-active" data-v-67e96130><img src="/avatar.jpg" data-v-67e96130></a> <hgroup class="introduce" data-v-67e96130><div class="nickname" data-v-67e96130>zzqhost</div> <a title="zzqhost@163.com" class="mail" data-v-67e96130>zzqhost@163.com</a></hgroup></div></div></li> <li role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left:20px;color:;background-color:;" data-v-67e96130><i class="iconfont icon-home" data-v-67e96130></i> <span class="item-title" data-v-67e96130>主页</span></li> <li role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left:20px;color:;background-color:;" data-v-67e96130><i class="iconfont icon-biaoqian" data-v-67e96130></i> <span class="item-title" data-v-67e96130>标签分类</span></li> <li role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left:20px;color:;background-color:;" data-v-67e96130><i class="iconfont icon-wenzhang" data-v-67e96130></i> <span class="item-title" data-v-67e96130>时间归档</span></li> <!----> <li role="menuitem" tabindex="-1" class="el-menu-item" style="padding-left:20px;color:;background-color:;" data-v-67e96130><i class="iconfont icon-aboutme" data-v-67e96130></i> <span class="item-title" data-v-67e96130>自我介绍</span></li></ul></aside> <section class="el-container container-warp" data-v-80d5f2bc><header id="topHeader" class="el-header top-header" style="height:60px;padding-left:260px;" data-v-1a942948 data-v-80d5f2bc><div class="header-warp el-row is-align-middle el-row--flex" data-v-1a942948><div class="el-col el-col-12 el-col-xs-7" data-v-1a942948><div class="el-row is-align-middle el-row--flex" data-v-1a942948><div class="el-col el-col-2" data-v-1a942948><button type="button" class="el-button el-button--primary is-circle" data-v-1a942948><!----><!----><span><i class="iconfont icon-caidan" data-v-1a942948></i></span></button></div></div></div> <div class="el-col el-col-20 el-col-xs-24" data-v-1a942948><div class="grid-content bg-purple-light" data-v-1a942948><div class="el-row is-justify-end is-align-middle el-row--flex" data-v-1a942948><div class="el-col el-col-13 el-col-xs-24 el-col-sm-21 el-col-md-17 el-col-lg-13" data-v-1a942948><div aria-haspopup="listbox" role="combobox" aria-owns="el-autocomplete-3504" class="el-autocomplete search-input" data-v-1a942948><div class="el-input el-input--small el-input--suffix"><!----><input type="text" autocomplete="off" valueKey="value" popperClass="search-popper" placeholder="搜搜看" fetchSuggestions="function () { [native code] }" debounce="300" placement="bottom-start" popperAppendToBody="true" value="" class="el-input__inner"><!----><span class="el-input__suffix"><span class="el-input__suffix-inner"><i class="el-input__icon el-icon-search search-ico" data-v-1a942948></i><!----></span><!----></span><!----></div><div role="region" class="el-autocomplete-suggestion el-popper search-popper" style="width:;display:none;"><div class="el-scrollbar"><div class="el-autocomplete-suggestion__wrap el-scrollbar__wrap el-scrollbar__wrap--hidden-default"><ul class="el-scrollbar__view el-autocomplete-suggestion__list"></ul></div><div class="el-scrollbar__bar is-horizontal"><div class="el-scrollbar__thumb" style="width:0;transform:translateX(0%);ms-transform:translateX(0%);webkit-transform:translateX(0%);"></div></div><div class="el-scrollbar__bar is-vertical"><div class="el-scrollbar__thumb" style="height:0;transform:translateY(0%);ms-transform:translateY(0%);webkit-transform:translateY(0%);"></div></div></div></div></div></div></div></div></div></div></header> <main class="el-main my-main" style="margin-left:240px;" data-v-105de776 data-v-80d5f2bc><div class="content-header index-header" data-v-60d87e45 data-v-105de776><div class="container fade-scale in" data-v-60d87e45><h1 id="conentHeader" class="title" data-v-60d87e45>Android快速加载Dex</h1> <h5 class="subtitle" data-v-60d87e45>最后更新时间：2019-07-04 18:08:36</h5></div></div> <div data-v-95d4b5b2 data-v-105de776 data-v-105de776><div class="post-content el-row is-justify-center el-row--flex" data-v-95d4b5b2><div id="post-card" class="post-card post-sign el-col el-col-16 el-col-xs-24 el-col-sm-23 el-col-md-23 el-col-lg-16" data-v-95d4b5b2><div class="content__default" data-v-95d4b5b2><p>DexFile类的LoadDex方法可以动态加载Dex文件，但是，这个类有一个缺陷，就是第一次启动并加载一个dex文件时，（尤其在ART模式）需要花费很长的时间。因为它会执行一次dexopt（art以下）或dex2oat（art及以上）操作。
正常情况下不会感觉到它的不足，但是当你在App中使用插件化框架的时候，这个缺点会放大。
本篇总结了几个解决此问题的方法
</p> <h1 id="目前的一些解决方案"><a href="#目前的一些解决方案" aria-hidden="true" class="header-anchor">#</a> 目前的一些解决方案</h1> <h2 id="turbodex"><a href="#turbodex" aria-hidden="true" class="header-anchor">#</a> TurboDex</h2> <p>早在2016年的GMTC会议时，Lody就已经在做TurboDex了，当时没有细聊，只知道Lody做了并开源了一个这样的东西，可以瞬间加载Dex文件。 今天有空研究了一下，现总结说明一下其原理</p> <h3 id="介绍"><a href="#介绍" aria-hidden="true" class="header-anchor">#</a> 介绍</h3> <blockquote><p>众所周知,Android中在Runtime加载一个 未优化的Dex文件 (尤其在 ART 模式)需要花费 很长的时间. 当你在App中使用 插件化框架 的时候, 首次加载插件就需要耗费很长的时间.</p></blockquote> <blockquote><p>TurboDex 就是为了解决这一问题而生, 就像是给AndroidVM开启了上帝模式, 在引入TurboDex后, 无论你加载了多大的Dex文件,都可以在毫秒级别内完成.</p></blockquote> <h3 id="原理"><a href="#原理" aria-hidden="true" class="header-anchor">#</a> 原理</h3> <ul><li><p>请参考以下的源码
#define HOOK(func) Cydia::elfHookFunction(&quot;libc.so&quot;, #func, (void*) my_##func, (void**) &amp;org_##func)</p> <pre><code>  static bool hooked = false;
  static bool enable = false;

  int (*org_execv)(const char *name, char **argv);

  int my_execv(const char *name, char **argv) {
  		#ifdef DEBUG
  		LOGD(&quot;#execv %s.&quot;, name);
  		#endif

  		if(enable &amp;&amp; strcmp(name, DEX2OAT_BIN) == 0) {
  			exit(0);
  		}

    		return org_execv(name, argv);
  }

  void enableFastLoadDex() {
  	if(!hooked) {
  		HOOK(execv);
  		hooked = true;
  	}
  	enable = true;
  }
</code></pre></li> <li><p><strong>它的实现原理就是Hook了libc.so中的execv函数，在其执行时，检查是否是要调用dex2oat，如果是的话，直接退出</strong></p></li> <li><p>实现跟下边的<a href="%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%AA%E5%BF%AB%E9%80%9F%E5%8A%A0%E8%BD%BDdex%E6%96%87%E4%BB%B6%E7%9A%84%E6%96%B9%E6%B3%95">看雪论坛</a>中的一篇文章写的是一样的</p></li></ul> <h2 id="看雪论坛中的一篇文章"><a href="#看雪论坛中的一篇文章" aria-hidden="true" class="header-anchor">#</a> 看雪论坛中的一篇文章</h2> <ul><li>它的实现原理就是Hook了libc.so中的execv函数，在其执行时，检查是否是要调用dex2oat，如果是的话，直接退出</li> <li>具体参考<a href="%E5%88%86%E4%BA%AB%E4%B8%80%E4%B8%AA%E5%BF%AB%E9%80%9F%E5%8A%A0%E8%BD%BDdex%E6%96%87%E4%BB%B6%E7%9A%84%E6%96%B9%E6%B3%95">《分享一个快速加载dex文件的方法》</a></li></ul> <h2 id="tinker"><a href="#tinker" aria-hidden="true" class="header-anchor">#</a> Tinker</h2> <h3 id="技术文章中的线索"><a href="#技术文章中的线索" aria-hidden="true" class="header-anchor">#</a> 技术文章中的线索</h3> <p>在Tinker分享的技术文章中有这样一段话</p> <blockquote><p>九、厂商OTA后应用启动耗时问题</p></blockquote> <blockquote><p>在系统OTA后，旧的补丁的oat文件都已经过期。系统会在首次加载时，会重新执行dex2oat。这导致可能会在前台等待很长的时间，甚至出现ANR。这也是Vivo在某次会议上点名批评Tinker的最大原因。</p></blockquote> <blockquote><p>事实上，我们并非没有努力过。更早的时候，我们花费了1个多月的时间实现了分平台合成方案。即在Dalvik合成全量的Dex，在Art合成一个小的Dex。同一个输入，生成不同的并且合法的输出。这个的确不容易，我们也是踩过无数的坑，无数次尝试才实现。但是由于Art的内联问题，这个方案需要废弃。</p></blockquote> <blockquote><p>还有什么样的方案？这个时候，厂商给我们抛出橄榄枝，可以给微信做单独的优化：</p></blockquote> <blockquote><p>在系统升级时，帮助微信把Tinker目录的odex文件重新做dex2oat;
首次调用补丁dex2oat时，采用类似Oppo/Vivo的异步策略。
但是个人坚决反对这些特殊的优化，如果没有做定制的厂商怎么办？外部使用Tinker的应用怎么办？这不是一个非常良好的选择。如何解决：</p></blockquote> <blockquote><p>回退版本；检测到厂商OTA之后，我们立刻删除补丁，然后再在后台异步重新做dex2oat。这个方法非常简单，看起来也的确可以解决OTA的问题，但大范围的回退版本是否会造成更大的问题，尽管只是短暂的回退。假设我某次补丁修改了某些数据库的结构？所以这个方案是不能采用的。</p></blockquote> <blockquote><p>弹等待框；看起来厂商OTA的间隔不会非常频繁，如果使用等待框的方式用户也可以接受。这个我们采用的方案是当检测到系统OTA后，使用单独的进程去展示等待框。看起来好像没问题，但是这个有个非常大的问题，当主进程dex2oat超过60S的时候，一样会由于bg anr被系统杀死。这个方案在Commit中提交，很快被删除了。但是这套代码其实可以应用在Dalvik的多dex加载，大家可以参考一下。</p></blockquote> <blockquote><p><strong>解释执行</strong>；受Oppo/Vivo异步执行dex2oat启发，我们是否可以在OTA的首次先使用解释模式执行odex文件，在后台再做异步的dex2oat?事实上，这也是我们最终采用的方案。但是这里要注意的细节其实非常多，如果判断解释执行成功，解释执行的命令参数如何拼写，instruction set如何获取？大家可以参考这个Commit.</p></blockquote> <h2 id="源码分析"><a href="#源码分析" aria-hidden="true" class="header-anchor">#</a> 源码分析</h2> <ul><li><p><strong>源码文件</strong> tinker-android/tinker-android-loader/src/main/java/com/tencent/tinker/loader/TinkerParallelDexOptimizer.java</p></li> <li><p>在这里有一个解释执行的判断
if (useInterpretMode) {
interpretDex2Oat(dexFile.getAbsolutePath(), optimizedPath);
} else {
DexFile.loadDex(dexFile.getAbsolutePath(), optimizedPath, 0);
}</p></li> <li><p>interpretDex2Oat函数的实现如下
private void interpretDex2Oat(String dexFilePath, String oatFilePath) throws IOException {</p> <pre><code>      final File oatFile = new File(oatFilePath);
      if (!oatFile.exists()) {
          oatFile.getParentFile().mkdirs();
      }

      final List&lt;String&gt; commandAndParams = new ArrayList&lt;&gt;();
      commandAndParams.add(&quot;dex2oat&quot;);
      commandAndParams.add(&quot;--dex-file=&quot; + dexFilePath);
      commandAndParams.add(&quot;--oat-file=&quot; + oatFilePath);
      commandAndParams.add(&quot;--instruction-set=&quot; + targetISA);
      commandAndParams.add(&quot;--compiler-filter=interpret-only&quot;);

      final ProcessBuilder pb = new ProcessBuilder(commandAndParams);
      pb.redirectErrorStream(true);
      final Process dex2oatProcess = pb.start();
      StreamConsumer.consumeInputStream(dex2oatProcess.getInputStream());
      StreamConsumer.consumeInputStream(dex2oatProcess.getErrorStream());
      try {
          final int ret = dex2oatProcess.waitFor();
          if (ret != 0) {
              throw new IOException(&quot;dex2oat works unsuccessfully, exit code: &quot; + ret);
          }
      } catch (InterruptedException e) {
          throw new IOException(&quot;dex2oat is interrupted, msg: &quot; + e.getMessage(), e);
      }
  }
</code></pre></li> <li><p>源码分析</p> <ul><li>tinker的源码中是通过调用系统中的命令<strong>dex2oat</strong>并通过传递特定的参数来达到解释执行的目的</li> <li>关键参数： --compiler-filter=interpret-only</li> <li>--compiler-filter官方解释
--compiler-filter=(verify-none|interpret-only|space|balanced|speed|everything|time):
select compiler filter.
Example: --compiler-filter=everything
Default: speed</li> <li><a href="http://blog.csdn.net/roland_sun/article/details/50234551" target="_blank" rel="noopener noreferrer">参数总结<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></li></ul> <h1 id="总结"><a href="#总结" aria-hidden="true" class="header-anchor">#</a> 总结</h1> <table><thead><tr><th>方案</th> <th>原理</th> <th>适用场景</th></tr></thead> <tbody><tr><td>TurboDex</td> <td>调用DexFile.LoadDex然后Hook libc.so</td> <td>简单暴力，适用于不改动原代码的情况下</td></tr> <tr><td>Tinker</td> <td>直接调用dex2oat命令</td> <td>适用于自己全面掌控代码的情况下</td></tr></tbody></table> <h1 id="另一个问题"><a href="#另一个问题" aria-hidden="true" class="header-anchor">#</a> 另一个问题</h1> <p>DexFile类中的方法loadDex已经在api level 26中被废弃了，如下</p> <blockquote><p>loadDex(String sourcePathName, String outputPathName, int flags)</p></blockquote> <blockquote><p>This method was <strong>deprecated</strong> in API level O. Applications should use one of the standard classloaders such as PathClassLoader instead. This API will be removed in a future Android release.</p></blockquote> <p>看来使用dex2oat这个方案还靠谱些；而且有必要再研究一下其它的方案</p> <h1 id="参考"><a href="#参考" aria-hidden="true" class="header-anchor">#</a> 参考</h1> <ul><li><a href="https://github.com/asLody/TurboDex/blob/master/CHINESE.md" target="_blank" rel="noopener noreferrer">TurboDex: 在Android瞬间加载Dex<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="http://note.youdao.com/share/?id=28e62692d218a1f1faef98e4e7724f22&amp;type=note#/" target="_blank" rel="noopener noreferrer">TurboDex瞬间实现加载Dex的分析<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="http://bbs.pediy.com/thread-205577.htm" target="_blank" rel="noopener noreferrer">分享一个快速加载dex文件的方法<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://mp.weixin.qq.com/s/tlDy6kx8qVHQOZjNpG514w" target="_blank" rel="noopener noreferrer">Tinker：技术的初心与坚持<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="http://blog.csdn.net/roland_sun/article/details/50234551" target="_blank" rel="noopener noreferrer">dex2oat程序参数总结<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li> <li><a href="https://developer.android.com/reference/dalvik/system/DexFile.html" target="_blank" rel="noopener noreferrer">AndroidDeveloper<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></li></ul></div> <span id="footerPost" data-v-95d4b5b2></span></div> <div id="post-toc" class="post-toc el-col el-col-6" data-v-95d4b5b2><h4 class="catalog-title" data-v-95d4b5b2>TOC</h4> <div class="catalog-body" data-v-95d4b5b2><ul id="catalog-list" class="catalog-list" data-v-95d4b5b2></ul></div></div></div> <div class="post-nav el-row is-justify-space-around el-row--flex" data-v-95d4b5b2><div class="post-prev el-col el-col-7" data-v-95d4b5b2><div data-v-95d4b5b2><a href="/posts/ClassLoader%E8%AF%A6%E8%A7%A3.html" data-v-95d4b5b2><i class="el-icon-arrow-left" data-v-95d4b5b2></i> Prev
        </a> <p class="nav-title" data-v-95d4b5b2>ClassLoader详解</p></div></div> <div class="post-next el-col el-col-7 el-col-lg-pull-5" data-v-95d4b5b2><div data-v-95d4b5b2><a href="/posts/%E5%AD%97%E7%AC%A6%E7%BC%96%E7%A0%81.html" data-v-95d4b5b2>
          Next
          <i class="el-icon-arrow-right" data-v-95d4b5b2></i></a> <p class="nav-title" data-v-95d4b5b2>字符编码</p></div></div></div> <div class="el-row is-justify-center el-row--flex" data-v-95d4b5b2></div> <span data-v-d999c3f2 data-v-95d4b5b2><button type="button" class="el-button toc-btn el-button--primary is-circle" data-v-d999c3f2><!----><!----><span><i class="iconfont icon-service-directory" data-v-d999c3f2></i></span></button> <button type="button" class="el-button gotop-btn el-button--primary is-circle" data-v-d999c3f2><!----><!----><span><i class="el-icon-arrow-up" data-v-d999c3f2></i></span></button></span></div></main></section> <button type="button" class="el-button gotop-btn el-button--primary is-circle" style="display:none;" data-v-78a2dcfa data-v-80d5f2bc><!----><!----><span><i class="el-icon-arrow-up" data-v-78a2dcfa></i></span></button></section> <footer class="el-footer container-footer" style="height:60px;" data-v-76c50ee3 data-v-80d5f2bc><div class="footer-warp el-row is-justify-center is-align-center el-row--flex footerMargin" data-v-76c50ee3><div class="footer-top el-col el-col-24" data-v-76c50ee3><p class="ellipsis" data-v-76c50ee3><span data-v-76c50ee3>
          博客内容遵循
          <a rel="license" href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" data-v-76c50ee3>知识共享 署名 - 非商业性 - 相同方式共享 4.0 国际协议</a></span></p></div> <div class="footer-bottom el-col el-col-24" data-v-76c50ee3><p class="ellipsis" data-v-76c50ee3><span data-v-76c50ee3><span data-v-76c50ee3>
            张志强的博客 © 2017-01 ~ 2021-03
          </span></span> <span data-v-76c50ee3>
          Power by
          <a href="https://vuepress.vuejs.org/zh/" target="_blank" data-v-76c50ee3>VuePress</a> Theme
          <a href="https://github.com/zhhlwd/vuepress-theme-indigo-material" target="_blank" data-v-76c50ee3>indigo material</a></span></p></div></div></footer> <div class="overlay" data-v-80d5f2bc></div></div><div class="global-ui"></div></div>
    <script src="/assets/js/app.3e01f5cb.js" defer></script><script src="/assets/js/1.21aaee9f.js" defer></script><script src="/assets/js/14.98a4de9c.js" defer></script><script src="/assets/js/5.352c1a43.js" defer></script><script src="/assets/js/7.4a8a313c.js" defer></script><script src="/assets/js/9.5ce2172b.js" defer></script><script src="/assets/js/6.8b8fad13.js" defer></script><script src="/assets/js/22.7d278bc3.js" defer></script><script src="/assets/js/13.186562af.js" defer></script><script src="/assets/js/15.740f4afc.js" defer></script>
  </body>
</html>
